Flutter এ Custom Widgets তৈরি

Mobile App Development - ফ্লাটার (Flutter)
330

Flutter এ Custom Widgets তৈরি করা হলো একটি অত্যন্ত শক্তিশালী ফিচার, যা আপনাকে পুনঃব্যবহারযোগ্য, মডুলার, এবং কাস্টমাইজড UI উপাদান তৈরিতে সহায়তা করে। Flutter এর Widget-ভিত্তিক আর্কিটেকচার আপনাকে সহজেই নতুন উইজেট তৈরি করতে দেয়, যা অ্যাপ্লিকেশনের বিভিন্ন জায়গায় পুনরায় ব্যবহার করা যায় এবং কোড পরিষ্কার এবং সংগঠিত থাকে।

Custom Widget তৈরি করার প্রকারভেদ:

  1. Stateless Widget: এটি এমন উইজেট, যার স্টেট (অবস্থা) পরিবর্তন হয় না। সাধারণত, UI এ স্থির উপাদান প্রদর্শনের জন্য ব্যবহৃত হয়।
  2. Stateful Widget: এটি এমন উইজেট, যার স্টেট পরিবর্তন হতে পারে। সাধারণত, ইন্টারেকটিভ উপাদান এবং ডাইনামিক কনটেন্ট প্রদর্শনের জন্য ব্যবহৃত হয়।
  3. Inherited Widget: এটি ডেটা এবং স্টেট ম্যানেজমেন্টের জন্য ব্যবহার করা হয়, যেখানে একাধিক উইজেটের মধ্যে ডেটা শেয়ার করা হয়।

Custom Stateless Widget তৈরি করা:

Stateless Widget এমন একটি উইজেট, যার অবস্থা (স্টেট) ইনস্ট্যান্টশিয়েশন এর পর পরিবর্তিত হয় না। এটি সাধারণত স্ট্যাটিক কনটেন্ট প্রদর্শনের জন্য ব্যবহৃত হয়।

Stateless Widget এর উদাহরণ:

import 'package:flutter/material.dart';

class CustomButton extends StatelessWidget {
  final String text;
  final VoidCallback onPressed;

  CustomButton({required this.text, required this.onPressed});

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: onPressed,
      style: ElevatedButton.styleFrom(
        primary: Colors.blue,
        padding: EdgeInsets.symmetric(horizontal: 20, vertical: 15),
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(10),
        ),
      ),
      child: Text(
        text,
        style: TextStyle(color: Colors.white, fontSize: 18),
      ),
    );
  }
}

ব্যাখ্যা:

  • CustomButton: একটি Stateless Widget, যা একটি কাস্টম বাটন তৈরি করে।
  • text এবং onPressed: কন্সট্রাক্টর এর মাধ্যমে প্রোপার্টি হিসেবে পাস করা হয়।
  • ElevatedButton: বাটনটি কাস্টমাইজ করে প্রদর্শন করা হয়, যেমন রঙ, প্যাডিং, এবং বর্ডার।

ব্যবহার:

CustomButton(
  text: 'Click Me',
  onPressed: () {
    print('Button pressed!');
  },
);

Custom Stateful Widget তৈরি করা:

Stateful Widget হলো এমন একটি উইজেট, যার স্টেট পরিবর্তন হতে পারে। এটি সাধারণত ডাইনামিক কনটেন্ট এবং ইন্টারেকটিভ উপাদান প্রদর্শনের জন্য ব্যবহৃত হয়।

Stateful Widget এর উদাহরণ:

import 'package:flutter/material.dart';

class ToggleSwitch extends StatefulWidget {
  @override
  _ToggleSwitchState createState() => _ToggleSwitchState();
}

class _ToggleSwitchState extends State<ToggleSwitch> {
  bool _isOn = false;

  void _toggleSwitch() {
    setState(() {
      _isOn = !_isOn;
    });
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: _toggleSwitch,
      child: Container(
        width: 100,
        height: 50,
        decoration: BoxDecoration(
          color: _isOn ? Colors.green : Colors.red,
          borderRadius: BorderRadius.circular(25),
        ),
        alignment: _isOn ? Alignment.centerRight : Alignment.centerLeft,
        padding: EdgeInsets.symmetric(horizontal: 5),
        child: Container(
          width: 40,
          height: 40,
          decoration: BoxDecoration(
            color: Colors.white,
            shape: BoxShape.circle,
          ),
        ),
      ),
    );
  }
}

ব্যাখ্যা:

  • ToggleSwitch: একটি Stateful Widget, যা একটি সুইচ তৈরি করে।
  • _isOn: একটি বুলিয়ান ভ্যারিয়েবল, যা সুইচের বর্তমান অবস্থা (অন/অফ) সংরক্ষণ করে।
  • _toggleSwitch: একটি ফাংশন, যা GestureDetector এর মাধ্যমে ট্যাপ করলে স্টেট পরিবর্তন করে।
  • Container: সুইচের আউটলাইন এবং ইন্টারনাল বল তৈরি করে।

ব্যবহার:

ToggleSwitch(),

Custom Inherited Widget তৈরি করা:

Inherited Widget ব্যবহৃত হয় উইজেট ট্রিতে ডেটা শেয়ার করার জন্য, যেখানে একাধিক উইজেট একই ডেটা অ্যাক্সেস করতে পারে। এটি ডেটা ম্যানেজমেন্ট এবং স্টেট শেয়ারের জন্য গুরুত্বপূর্ণ।

Inherited Widget এর উদাহরণ:

import 'package:flutter/material.dart';

class CounterProvider extends InheritedWidget {
  final int counter;
  final Widget child;

  CounterProvider({required this.counter, required this.child}) : super(child: child);

  static CounterProvider? of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<CounterProvider>();
  }

  @override
  bool updateShouldNotify(CounterProvider oldWidget) {
    return oldWidget.counter != counter;
  }
}

class InheritedWidgetExample extends StatefulWidget {
  @override
  _InheritedWidgetExampleState createState() => _InheritedWidgetExampleState();
}

class _InheritedWidgetExampleState extends State<InheritedWidgetExample> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return CounterProvider(
      counter: _counter,
      child: Scaffold(
        appBar: AppBar(title: Text('Inherited Widget Example')),
        body: Center(child: CounterDisplay()),
        floatingActionButton: FloatingActionButton(
          onPressed: _incrementCounter,
          child: Icon(Icons.add),
        ),
      ),
    );
  }
}

class CounterDisplay extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final counter = CounterProvider.of(context)?.counter ?? 0;
    return Text('Counter: $counter', style: TextStyle(fontSize: 24));
  }
}

ব্যাখ্যা:

  • CounterProvider: এটি একটি Inherited Widget, যা counter নামের ভ্যারিয়েবল শেয়ার করে।
  • updateShouldNotify: পুরনো এবং নতুন ডেটা তুলনা করে, যাতে জানায় স্টেট আপডেট হয়েছে কি না।
  • of(context): উইজেট ট্রি থেকে ডেটা অ্যাক্সেস করার জন্য একটি স্ট্যাটিক মেথড।
  • CounterDisplay: একটি Stateless Widget, যা CounterProvider এর মাধ্যমে ডেটা প্রদর্শন করে।

Custom Widgets তৈরির সেরা চর্চা:

  1. Modularity বজায় রাখুন: উইজেটকে ছোট এবং পুনঃব্যবহারযোগ্য করে তৈরি করুন, যাতে এটি অ্যাপের অন্যান্য অংশে সহজে ব্যবহার করা যায়।
  2. Props এবং State ব্যবহার করুন: প্রোপার্টি এবং স্টেট ব্যবহারের মাধ্যমে উইজেটকে কনফিগারযোগ্য এবং ডাইনামিক রাখুন।
  3. Styling and Theming ব্যবহার করুন: কাস্টম উইজেট তৈরির সময় স্টাইলিং এবং থিমিং কনসেপ্ট ফলো করুন, যাতে অ্যাপের থিমের সাথে সামঞ্জস্যপূর্ণ হয়।
  4. Performance অপ্টিমাইজ করুন: যেসব উইজেটে ফ্রিকোয়েন্ট স্টেট পরিবর্তন হয়, সেখানে setState ব্যবহার করার সময় সতর্ক থাকুন এবং রিড্রো প্রতিরোধের জন্য AnimatedBuilder এবং AnimatedWidget ব্যবহার করুন।

Flutter এ Custom Widgets এর উপযোগিতা:

  • পুনঃব্যবহারযোগ্য: একই কোড বারবার না লিখে একটি উইজেট তৈরি করে বিভিন্ন জায়গায় ব্যবহার করা যায়।
  • কোড পরিষ্কার: কোডকে মডুলার এবং সংগঠিত রাখে, যা বুঝতে এবং মেইনটেইন করতে সহজ।
  • পরীক্ষা ও ডিবাগ করা সহজ: আলাদা উইজেট তৈরি করলে তাদের আলাদা করে পরীক্ষা এবং ডিবাগ করা যায়।

Flutter এ Custom Widgets তৈরি করে আপনি আপনার অ্যাপ্লিকেশনকে মডুলার, ডাইনামিক, এবং রিইউজেবল রাখতে পারবেন, যা অ্যাপের পারফরম্যান্স এবং ইউজার এক্সপেরিয়েন্সকে উন্নত করে।

Content added By

Custom Widgets এর প্রয়োজনীয়তা এবং ধারণা

204

Flutter এ Custom Widgets তৈরি করা খুবই গুরুত্বপূর্ণ, কারণ এগুলোর মাধ্যমে আপনি অ্যাপের জন্য পুনঃব্যবহারযোগ্য, মডুলার, এবং কাস্টমাইজেবল UI উপাদান তৈরি করতে পারেন। Flutter এ সবকিছুই Widget, তাই কাস্টম Widget তৈরি করা আপনাকে আরও কার্যকরভাবে কোড লিখতে এবং UI ডিজাইন করতে সাহায্য করে। নিচে Custom Widget এর প্রয়োজনীয়তা এবং এর ধারণা বিস্তারিতভাবে আলোচনা করা হলো।

Custom Widgets এর প্রয়োজনীয়তা:

  1. পুনঃব্যবহারযোগ্য কোড:
    • Custom Widgets ব্যবহার করে আপনি একই কোড বা UI উপাদান একাধিক স্থানে পুনঃব্যবহার করতে পারেন। এতে কোড ডুপ্লিকেশন কম হয় এবং অ্যাপের রক্ষণাবেক্ষণ সহজ হয়।
  2. কোড পরিষ্কার এবং সংগঠিত রাখা:
    • যখন একটি UI জটিল হয়, তখন সবকিছু এক জায়গায় রাখা কঠিন হয়ে যায়। Custom Widgets ব্যবহার করে আপনি UI উপাদানগুলোকে ছোট ছোট অংশে ভাগ করতে পারেন, যা কোডকে পরিষ্কার এবং সহজবোধ্য করে।
  3. মডুলার ডিজাইন:
    • Custom Widgets এর মাধ্যমে আপনি UI কে মডুলারভাবে ডিজাইন করতে পারেন, যেখানে প্রতিটি Widget একটি নির্দিষ্ট কাজ সম্পন্ন করে। এটি ডিজাইন পরিবর্তন বা আপডেট করা সহজ করে তোলে।
  4. সহজে কাস্টমাইজেশন:
    • Custom Widgets তৈরি করলে আপনি বিভিন্ন প্রপার্টি এবং স্টাইলিং প্যারামিটার যুক্ত করতে পারেন, যা আপনাকে আপনার অ্যাপের ডিজাইনকে সহজেই কাস্টমাইজ করতে দেয়।
  5. ডিবাগিং এবং টেস্টিং সহজ করা:
    • ছোট ছোট Custom Widgets এ কোড ভাগ করলে ডিবাগিং এবং টেস্টিং সহজ হয়। প্রতিটি Widget আলাদাভাবে পরীক্ষা করা যায় এবং সমস্যাগুলো সহজে চিহ্নিত করা যায়।

Custom Widget এর ধারণা:

Flutter এ Custom Widget এমন একটি Widget যা আপনি নিজের প্রয়োজন অনুযায়ী তৈরি করেন এবং এটি পুনঃব্যবহারযোগ্য। এটি সাধারণত দুই ধরণের হতে পারে:

  1. StatelessWidget:
    • এই Widget এমন উপাদানের জন্য ব্যবহার করা হয় যা স্টেট পরিবর্তন করে না। এটি সাধারণত স্থির UI উপাদান তৈরি করতে ব্যবহৃত হয়।
  2. StatefulWidget:
    • এই Widget এমন উপাদানের জন্য ব্যবহার করা হয় যেগুলোতে স্টেট পরিবর্তন হতে পারে। এটি ডাইনামিক UI উপাদান তৈরি করতে ব্যবহৃত হয়, যেখানে ইউজারের ইন্টারঅ্যাকশন বা ডেটার পরিবর্তন অনুসারে UI আপডেট হয়।

Custom Widget এর উদাহরণ (StatelessWidget):

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Custom Widget Example',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Custom Widget Demo'),
        ),
        body: Center(
          child: CustomButton(
            text: 'Click Me',
            onPressed: () {
              print('Button Clicked!');
            },
          ),
        ),
      ),
    );
  }
}

// Custom StatelessWidget
class CustomButton extends StatelessWidget {
  final String text;
  final VoidCallback onPressed;

  CustomButton({required this.text, required this.onPressed});

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: onPressed,
      style: ElevatedButton.styleFrom(
        padding: EdgeInsets.symmetric(horizontal: 20, vertical: 15),
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(10),
        ),
      ),
      child: Text(text),
    );
  }
}

উদাহরণের ব্যাখ্যা:

  1. CustomButton: এখানে একটি কাস্টম StatelessWidget তৈরি করা হয়েছে যাকে CustomButton বলা হচ্ছে। এটি দুটি প্রপার্টি গ্রহণ করে: text এবং onPressed.
  2. text: বাটনের মধ্যে প্রদর্শিত টেক্সট।
  3. onPressed: একটি কলব্যাক ফাংশন যা বাটনে ক্লিক করলে কার্যকর হবে।
  4. build মেথডে ElevatedButton ব্যবহার করা হয়েছে যা প্রপার্টিগুলো গ্রহণ করে এবং UI তে একটি বাটন রেন্ডার করে।

Custom Widget এর উদাহরণ (StatefulWidget):

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Custom Stateful Widget Example',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Custom Stateful Widget Demo'),
        ),
        body: Center(
          child: CounterWidget(),
        ),
      ),
    );
  }
}

// Custom StatefulWidget
class CounterWidget extends StatefulWidget {
  @override
  _CounterWidgetState createState() => _CounterWidgetState();
}

class _CounterWidgetState extends State<CounterWidget> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text(
          'Counter: $_counter',
          style: TextStyle(fontSize: 24),
        ),
        SizedBox(height: 20),
        ElevatedButton(
          onPressed: _incrementCounter,
          child: Text('Increment'),
        ),
      ],
    );
  }
}

উদাহরণের ব্যাখ্যা:

  1. CounterWidget: এটি একটি কাস্টম StatefulWidget যা একটি কাউন্টার মান প্রদর্শন করে এবং একটি বাটন দিয়ে সেই মান বৃদ্ধি করে।
  2. State ম্যানেজমেন্ট: _CounterWidgetState_counter নামক একটি স্টেট ভেরিয়েবল তৈরি করা হয়েছে যা setState মেথডের মাধ্যমে আপডেট করা হয়।
  3. build মেথড: এই মেথডে একটি Column এর মধ্যে একটি টেক্সট এবং একটি বাটন রাখা হয়েছে। বাটনে ক্লিক করলে _incrementCounter মেথড কল হয়, যা _counter এর মান বাড়িয়ে দেয় এবং UI আপডেট হয়।

Custom Widgets এর সুবিধা:

  1. মডুলার এবং পুনঃব্যবহারযোগ্য: Custom Widgets কোড পুনঃব্যবহারযোগ্য করে এবং কোডকে ছোট ছোট মডিউলে ভাগ করে, যা ম্যানেজ করা সহজ হয়।
  2. কোড পরিষ্কার এবং সংগঠিত: জটিল UI ডিজাইন করলে, Custom Widgets ব্যবহার করে কোডকে সহজ ও পরিষ্কার রাখা যায়।
  3. সহজে কাস্টমাইজেশন: Custom Widgets বিভিন্ন প্রপার্টি এবং স্টাইলিং প্যারামিটার গ্রহণ করতে পারে, যা সহজে কাস্টমাইজেশন সম্ভব করে।
  4. ডিবাগিং এবং টেস্টিং সহজ: ছোট ছোট Custom Widgets এ কোড ভাগ করলে ডিবাগিং এবং টেস্টিং সহজ হয়। প্রতিটি Widget আলাদাভাবে পরীক্ষা করা যায়।

সংক্ষেপে:

  • Custom Widgets হলো পুনঃব্যবহারযোগ্য UI উপাদান যা Flutter অ্যাপে মডুলার, পরিষ্কার, এবং কাস্টমাইজেবল UI তৈরি করতে সহায়তা করে।
  • StatelessWidget এবং StatefulWidget এর মাধ্যমে বিভিন্ন ধরণের Custom Widgets তৈরি করা যায়।
  • Custom Widgets তৈরি করা হলে কোড রিডেবিলিটি বাড়ে এবং অ্যাপ ডেভেলপমেন্ট আরও সহজ হয়।

Custom Widgets ব্যবহার করে আপনি আপনার Flutter অ্যাপের UI ডিজাইনকে আরও উন্নত, মডুলার এবং কার্যকর করতে পারবেন।

Content added By

Reusable Widgets তৈরি করা

219

Flutter এ Reusable Widgets তৈরি করা হলো একটি গুরুত্বপূর্ণ প্র্যাকটিস, যা কোডকে পরিষ্কার, কার্যকরী এবং পুনরায় ব্যবহারযোগ্য করে তোলে। Reusable Widgets তৈরি করলে আপনি একই ধরনের UI এলিমেন্ট একাধিক জায়গায় ব্যবহার করতে পারেন, ফলে কোড রিডান্ডেন্সি কমে এবং কোড মেইনটেইন করা সহজ হয়। এটি বিশেষভাবে বড় এবং জটিল অ্যাপ্লিকেশন ডেভেলপ করার সময় গুরুত্বপূর্ণ।

Reusable Widgets তৈরি করার উপকারিতা:

  1. কোড রিডান্ডেন্সি কমানো: একই কোড একাধিকবার লেখার প্রয়োজন হয় না।
  2. কোড মেইনটেনেন্স সহজ করা: যদি কোনো চেঞ্জ করতে হয়, তাহলে শুধু উইজেট আপডেট করলেই সেই পরিবর্তন সব জায়গায় প্রয়োগ হয়।
  3. UI কনসিস্টেন্সি বজায় রাখা: Reusable Widgets ব্যবহার করে UI এলিমেন্টগুলোর ডিজাইন এবং ফাংশন একরকম রাখা যায়।
  4. কোড রিডেবিলিটি বাড়ানো: ছোট ছোট উইজেট তৈরি করে কোড আরো পড়তে এবং বুঝতে সহজ হয়।

Reusable Widget তৈরির ধাপসমূহ:

১. Stateless Widget ব্যবহার করে Reusable Widget তৈরি:

Stateless Widget ব্যবহার করে আপনি সাধারণত স্ট্যাটিক UI এলিমেন্ট যেমন বাটন, কার্ড, বা টেক্সট ব্লক তৈরি করতে পারেন, যেগুলোতে কোনো স্টেট পরিবর্তন হয় না।

উদাহরণ (Custom Button Widget):

import 'package:flutter/material.dart';

class CustomButton extends StatelessWidget {
  final String text;
  final VoidCallback onPressed;
  final Color color;

  const CustomButton({
    required this.text,
    required this.onPressed,
    this.color = Colors.blue,
  });

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: onPressed,
      style: ElevatedButton.styleFrom(primary: color),
      child: Text(text, style: TextStyle(color: Colors.white)),
    );
  }
}
  • CustomButton: এটি একটি Reusable Button Widget, যা text, onPressed এবং color প্যারামিটার হিসেবে গ্রহণ করে।
  • text: বাটনের টেক্সট।
  • onPressed: বাটনের ক্লিক ইভেন্ট হ্যান্ডেল করার জন্য একটি কোলব্যাক ফাংশন।
  • color: বাটনের রঙ কাস্টমাইজ করার জন্য।

ব্যবহার (Custom Button Widget):

CustomButton(
  text: 'Click Me',
  onPressed: () {
    print('Button Pressed!');
  },
  color: Colors.green,
)

২. Stateful Widget ব্যবহার করে Reusable Widget তৈরি:

Stateful Widget ব্যবহার করে আপনি এমন উইজেট তৈরি করতে পারেন যেগুলোতে স্টেট পরিবর্তন হয়। এটি সাধারণত ইনপুট ফিল্ড, টগল বাটন, বা ডাইনামিক UI এলিমেন্ট তৈরি করতে ব্যবহৃত হয়।

উদাহরণ (Custom Toggle Switch Widget):

import 'package:flutter/material.dart';

class CustomToggleSwitch extends StatefulWidget {
  final bool initialValue;
  final ValueChanged<bool> onChanged;

  const CustomToggleSwitch({
    required this.initialValue,
    required this.onChanged,
  });

  @override
  _CustomToggleSwitchState createState() => _CustomToggleSwitchState();
}

class _CustomToggleSwitchState extends State<CustomToggleSwitch> {
  late bool _isOn;

  @override
  void initState() {
    super.initState();
    _isOn = widget.initialValue;
  }

  void _toggleSwitch() {
    setState(() {
      _isOn = !_isOn;
      widget.onChanged(_isOn);
    });
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: _toggleSwitch,
      child: Container(
        width: 60,
        height: 30,
        decoration: BoxDecoration(
          color: _isOn ? Colors.green : Colors.grey,
          borderRadius: BorderRadius.circular(15),
        ),
        child: AnimatedAlign(
          duration: Duration(milliseconds: 200),
          alignment: _isOn ? Alignment.centerRight : Alignment.centerLeft,
          child: Container(
            width: 25,
            height: 25,
            decoration: BoxDecoration(
              color: Colors.white,
              shape: BoxShape.circle,
            ),
          ),
        ),
      ),
    );
  }
}
  • CustomToggleSwitch: এটি একটি Reusable Toggle Switch Widget, যা initialValue এবং onChanged প্যারামিটার নেয়।
  • _toggleSwitch(): এটি একটি ফাংশন যা টগল সুইচের স্টেট পরিবর্তন করে এবং প্যারেন্ট উইজেটকে নোটিফাই করে।
  • AnimatedAlign: এটি সুইচের মুভমেন্ট অ্যানিমেট করে।

ব্যবহার (Custom Toggle Switch Widget):

CustomToggleSwitch(
  initialValue: true,
  onChanged: (value) {
    print('Switch is now: $value');
  },
)

৩. Theme এবং Styling Reusable Widget:

Flutter এ Reusable Widget তৈরি করার সময় স্টাইলিং এবং থিম কনফিগার করার জন্য প্যারামিটার ব্যবহার করতে পারেন। এটি আপনাকে একই উইজেট ভিন্ন ভিন্ন স্টাইল বা থিম ব্যবহার করে ডাইনামিক্যালি কাস্টমাইজ করতে সাহায্য করবে।

উদাহরণ (Custom Card Widget):

import 'package:flutter/material.dart';

class CustomCard extends StatelessWidget {
  final Widget child;
  final Color backgroundColor;
  final double elevation;

  const CustomCard({
    required this.child,
    this.backgroundColor = Colors.white,
    this.elevation = 4.0,
  });

  @override
  Widget build(BuildContext context) {
    return Card(
      color: backgroundColor,
      elevation: elevation,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(12.0),
      ),
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: child,
      ),
    );
  }
}
  • CustomCard: এটি একটি Reusable Card Widget, যা child, backgroundColor, এবং elevation প্যারামিটার নেয়।
  • child: কার্ডের মধ্যে যেকোনো কন্টেন্ট প্রদর্শন করতে পারে।
  • backgroundColor এবং elevation: থিম এবং স্টাইলিং কাস্টমাইজ করার জন্য।

ব্যবহার (Custom Card Widget):

CustomCard(
  backgroundColor: Colors.lightBlueAccent,
  elevation: 8.0,
  child: Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      Text('Title', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
      SizedBox(height: 8),
      Text('This is a description inside a reusable card.'),
    ],
  ),
)

Reusable Widget তৈরির সেরা চর্চা:

  1. কোডকে পরিষ্কার রাখুন: উইজেট যত ছোট এবং সরল থাকবে, তত সহজে পুনঃব্যবহারযোগ্য হবে।
  2. প্যারামিটার ব্যবহার করুন: উইজেট কাস্টমাইজ করার জন্য প্যারামিটার এবং ডিফল্ট ভ্যালু ব্যবহার করুন, যা ডেভেলপমেন্টে সুবিধা দেবে।
  3. ফাংশন প্যারামিটার যোগ করুন: বাটন বা ইনপুট উইজেটের ক্ষেত্রে VoidCallback বা ValueChanged প্যারামিটার ব্যবহার করে ইভেন্ট হ্যান্ডলিং সহজ করুন।
  4. থিম এবং কাস্টম স্টাইলিং যোগ করুন: উইজেটে থিম এবং স্টাইল প্যারামিটার যোগ করে তা ডাইনামিক্যালি কাস্টমাইজযোগ্য রাখুন।

উপসংহার:

Flutter এ Reusable Widgets তৈরি করে আপনি কোডকে ক্লিন, মেইনটেইনেবল এবং স্কেলেবল করতে পারেন। Reusable Widgets আপনাকে অ্যাপ্লিকেশন ডেভেলপমেন্টে স্পিড বাড়াতে এবং UI কনসিস্টেন্সি বজায় রাখতে সহায়তা করে।

Content added By

CustomPainter দিয়ে Custom Drawing এবং Shapes

259

Flutter এ CustomPainter একটি শক্তিশালী টুল, যা ব্যবহার করে আপনি কাস্টম ড্রইং এবং শেপ তৈরি করতে পারেন। এটি আপনার অ্যাপ্লিকেশনে ডায়নামিক এবং আকর্ষণীয় ভিজ্যুয়াল ইফেক্ট, গ্রাফিক্স, এবং জ্যামিতিক শেপ তৈরি করতে সহায়ক। CustomPainter এর মাধ্যমে আপনি কাস্টমাইজড পেইন্টিং করতে পারেন, যেমন লাইনের কাজ, বৃত্ত, আয়তক্ষেত্র, গ্রেডিয়েন্ট, এবং অন্যান্য শেপ।

CustomPainter ব্যবহার করার প্রধান ধাপসমূহ:

  1. CustomPainter ক্লাস তৈরি করা: একটি ক্লাস তৈরি করুন, যা CustomPainter কে এক্সটেন্ড করে।
  2. paint() মেথড: এখানে ক্যানভাস এবং পেইন্ট অবজেক্ট ব্যবহার করে আপনার ড্রইং লজিক লিখুন।
  3. shouldRepaint() মেথড: এটি বলে দেয় কখন পুনরায় পেইন্ট করা উচিত।
  4. CustomPaint Widget: এটি ব্যবহার করে আপনার CustomPainter উইজেটটি Flutter এর উইজেট ট্রিতে যুক্ত করুন।

CustomPainter এর উদাহরণ:

Simple Line Drawing:

import 'package:flutter/material.dart';

class LinePainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.blue
      ..strokeWidth = 4.0
      ..style = PaintingStyle.stroke;

    canvas.drawLine(
      Offset(0, size.height / 2),
      Offset(size.width, size.height / 2),
      paint,
    );
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
  }
}

class LineDrawingExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Line Drawing Example')),
      body: Center(
        child: CustomPaint(
          size: Size(300, 300),
          painter: LinePainter(),
        ),
      ),
    );
  }
}

ব্যাখ্যা:

  • LinePainter: CustomPainter কে এক্সটেন্ড করে এবং paint মেথডে ড্রইং লজিক লিখেছে।
  • canvas.drawLine: এটি একটি সরল লাইন আঁকে, যেখানে Offset দ্বারা লাইনটির শুরু এবং শেষ পজিশন নির্ধারণ করা হয়েছে।
  • shouldRepaint: এখানে false রিটার্ন করে, কারণ এখানে স্ট্যাটিক পেইন্টিং হচ্ছে।

Custom Shape: Circle Drawing:

import 'package:flutter/material.dart';

class CirclePainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.green
      ..style = PaintingStyle.fill;

    final center = Offset(size.width / 2, size.height / 2);
    final radius = size.width / 4;

    canvas.drawCircle(center, radius, paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
  }
}

class CircleDrawingExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Circle Drawing Example')),
      body: Center(
        child: CustomPaint(
          size: Size(300, 300),
          painter: CirclePainter(),
        ),
      ),
    );
  }
}

ব্যাখ্যা:

  • CirclePainter: একটি বৃত্ত আঁকে এবং সেটি কেন্দ্রবিন্দু থেকে নির্ধারিত ব্যাসার্ধ নিয়ে।
  • canvas.drawCircle: এখানে ক্যানভাসের Offset (কেন্দ্র) এবং ব্যাসার্ধ পাস করা হয়েছে।

Custom Shape: Rectangle Drawing:

import 'package:flutter/material.dart';

class RectanglePainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.red
      ..style = PaintingStyle.stroke
      ..strokeWidth = 5.0;

    final rect = Rect.fromLTWH(50, 50, size.width - 100, size.height - 100);
    canvas.drawRect(rect, paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
  }
}

class RectangleDrawingExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Rectangle Drawing Example')),
      body: Center(
        child: CustomPaint(
          size: Size(300, 300),
          painter: RectanglePainter(),
        ),
      ),
    );
  }
}

ব্যাখ্যা:

  • RectanglePainter: একটি আয়তক্ষেত্র আঁকে, যেখানে Rect.fromLTWH ব্যবহার করা হয়েছে।
  • canvas.drawRect: ক্যানভাসে নির্দিষ্ট আকার এবং অবস্থানের রেকটেংগেল তৈরি করা হয়েছে।

Custom Path Drawing:

Flutter এ Path ক্লাস ব্যবহার করে আপনি জটিল শেপ এবং পাথ তৈরি করতে পারেন।

Custom Path (Triangle):

import 'package:flutter/material.dart';

class TrianglePainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.orange
      ..style = PaintingStyle.fill;

    final path = Path();
    path.moveTo(size.width / 2, 0);
    path.lineTo(size.width, size.height);
    path.lineTo(0, size.height);
    path.close();

    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
  }
}

class TriangleDrawingExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Triangle Drawing Example')),
      body: Center(
        child: CustomPaint(
          size: Size(300, 300),
          painter: TrianglePainter(),
        ),
      ),
    );
  }
}

ব্যাখ্যা:

  • TrianglePainter: একটি ত্রিভুজ আঁকে, যেখানে Path এবং lineTo ব্যবহার করা হয়েছে।
  • canvas.drawPath: ক্যানভাসে পাথ দ্বারা নির্ধারিত ত্রিভুজ আঁকে।

Custom Gradient Drawing:

Flutter এ কাস্টম গ্রেডিয়েন্ট তৈরি করা যায়, যা ব্যাকগ্রাউন্ড বা শেপে ব্যবহার করা যেতে পারে।

Gradient Circle:

import 'package:flutter/material.dart';

class GradientCirclePainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final rect = Rect.fromCircle(center: Offset(size.width / 2, size.height / 2), radius: size.width / 2);
    final gradient = RadialGradient(
      colors: [Colors.yellow, Colors.orange, Colors.red],
      stops: [0.0, 0.5, 1.0],
    );

    final paint = Paint()..shader = gradient.createShader(rect);
    canvas.drawCircle(Offset(size.width / 2, size.height / 2), size.width / 2, paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
  }
}

class GradientCircleExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Gradient Circle Example')),
      body: Center(
        child: CustomPaint(
          size: Size(300, 300),
          painter: GradientCirclePainter(),
        ),
      ),
    );
  }
}

ব্যাখ্যা:

  • RadialGradient: একটি সার্কুলার গ্রেডিয়েন্ট তৈরি করে, যা কেন্দ্র থেকে বাইরে ছড়ায়।
  • shader: পেইন্টের জন্য একটি শেডার তৈরি করা হয়, যা গ্রেডিয়েন্ট হিসেবে সেট করা হয়।

CustomPainter ব্যবহার করার সেরা চর্চা:

  1. Performance অপ্টিমাইজ করুন: shouldRepaint মেথডে এমন লজিক ব্যবহার করুন, যা বলে কখন পুনরায় পেইন্ট করা উচিত, যাতে অপ্রয়োজনীয় রিড্রো না হয়।
  2. Offscreen Buffer ব্যবহার করুন: RepaintBoundary ব্যবহার করে জটিল ড্রইংগুলোকে পারফরম্যান্স বাফারিং করা যায়।
  3. রেসপন্সিভ ডিজাইন: Size অবজেক্ট ব্যবহার করে ড্রইং করলে, এটি ডিভাইসের স্ক্রিন সাইজের সাথে মানানসই হয়।

উপসংহার:

Flutter এ CustomPainter ব্যবহার করে আপনি ডাইনামিক গ্রাফিক্স, জ্যামিতিক শেপ, গ্রেডিয়েন্ট, এবং অন্যান্য কাস্টম ডিজাইন তৈরি করতে পারেন। এটি আপনাকে আপনার অ্যাপ্লিকেশনকে ভিজ্যুয়ালি আকর্ষণীয় এবং ইন্টারেকটিভ করে তুলতে সহায়তা করে, যা ব্যবহারকারীর অভিজ্ঞতাকে উন্নত করে।

Content added By

Flutter এর মধ্যে Complex UI এবং Advanced Widgets তৈরি করা

213

Flutter এ Complex UI এবং Advanced Widgets তৈরি করা অত্যন্ত কার্যকর, কারণ Flutter এর সমৃদ্ধ Widget লাইব্রেরি এবং কাস্টমাইজেশনের ক্ষমতা ব্যবহার করে আপনি জটিল এবং আধুনিক UI ডিজাইন করতে পারেন। এটি আপনাকে Material Design এবং iOS স্টাইলের অ্যাপ্লিকেশন তৈরিতে সহায়তা করে। নিচে Complex UI এবং Advanced Widgets তৈরি করার প্রক্রিয়া এবং উদাহরণ আলোচনা করা হলো।

Complex UI তৈরি করার ধাপ:

ধাপ ১: UI কে ছোট ছোট Widget এ ভাগ করা:

  • Complex UI ডিজাইন করার প্রথম ধাপ হলো UI কে ছোট ছোট Widget এ ভাগ করা। প্রতিটি অংশের জন্য পৃথক Widget তৈরি করা হলে কোড মডুলার এবং পরিষ্কার থাকে। উদাহরণস্বরূপ, একটি প্রোফাইল স্ক্রিনে প্রোফাইল ছবি, নাম, এবং বায়ো আলাদাভাবে Widget হিসেবে তৈরি করা যেতে পারে।

ধাপ ২: Nested Widgets এবং Layouts ব্যবহার করা:

  • Flutter এ Row, Column, Stack, এবং ListView এর মত Layout Widget গুলো ব্যবহার করে Nested Widget এর মাধ্যমে Complex UI তৈরি করা যায়।
  • এই Layout Widgets গুলোর সাহায্যে আপনি Widget গুলোকে অনুভূমিক, উল্লম্ব বা স্তরে স্তরে (Layered) সাজাতে পারেন।

ধাপ ৩: Advanced Widgets এবং Custom Widgets ব্যবহার করা:

  • ListView.builder, GridView, CustomScrollView, এবং Sliver Widgets এর মত Advanced Widgets ব্যবহার করে জটিল এবং স্নিগ্ধ UI তৈরি করা যায়।
  • যখন প্রয়োজন হয়, তখন Custom Widget তৈরি করে UI কে আরও ডাইনামিক এবং পুনঃব্যবহারযোগ্য করা যায়।

Complex UI এর উদাহরণ (প্রোফাইল স্ক্রিন):

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Complex UI Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ProfileScreen(),
    );
  }
}

class ProfileScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Profile'),
      ),
      body: SingleChildScrollView(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            ProfileHeader(),
            SizedBox(height: 20),
            ProfileDetails(),
            SizedBox(height: 20),
            GallerySection(),
          ],
        ),
      ),
    );
  }
}

class ProfileHeader extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(20),
      color: Colors.blueAccent,
      child: Row(
        children: [
          CircleAvatar(
            radius: 40,
            backgroundImage: NetworkImage('https://via.placeholder.com/150'),
          ),
          SizedBox(width: 20),
          Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                'John Doe',
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 22,
                  fontWeight: FontWeight.bold,
                ),
              ),
              Text(
                'Flutter Developer',
                style: TextStyle(
                  color: Colors.white70,
                  fontSize: 16,
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

class ProfileDetails extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.all(20),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            'About Me',
            style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
          ),
          SizedBox(height: 10),
          Text(
            'I am a passionate Flutter developer with 3 years of experience in building cross-platform mobile applications.',
            style: TextStyle(fontSize: 16),
          ),
        ],
      ),
    );
  }
}

class GallerySection extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.all(20),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            'Gallery',
            style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
          ),
          SizedBox(height: 10),
          GridView.builder(
            shrinkWrap: true,
            physics: NeverScrollableScrollPhysics(),
            gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 3,
              crossAxisSpacing: 10,
              mainAxisSpacing: 10,
            ),
            itemCount: 6,
            itemBuilder: (context, index) {
              return Container(
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(10),
                  image: DecorationImage(
                    image: NetworkImage('https://via.placeholder.com/150'),
                    fit: BoxFit.cover,
                  ),
                ),
              );
            },
          ),
        ],
      ),
    );
  }
}

উদাহরণের ব্যাখ্যা:

ProfileHeader:

  • এটি একটি Row ব্যবহার করে প্রোফাইল ছবি এবং নাম প্রদর্শন করা হয়েছে।
  • CircleAvatar Widget ব্যবহার করে প্রোফাইল ছবির জন্য একটি বৃত্তাকার আকার তৈরি করা হয়েছে।

ProfileDetails:

  • একটি Column ব্যবহার করে "About Me" টেক্সট এবং বায়ো প্রদর্শন করা হয়েছে।

GallerySection:

  • GridView.builder ব্যবহার করে একটি গ্রিড তৈরি করা হয়েছে, যেখানে প্রোফাইল গ্যালারির ছবি গুলো সাজানো হয়েছে।
  • SliverGridDelegateWithFixedCrossAxisCount ব্যবহার করে গ্রিডের কলাম সংখ্যা এবং স্পেস নির্ধারণ করা হয়েছে।

Advanced Widgets এর উদাহরণ:

১. ListView.builder এবং Slivers:

  • ListView.builder: এটি একটি স্ক্রোলিং লিস্ট তৈরি করতে ব্যবহৃত হয় যেখানে ডাইনামিকভাবে আইটেমগুলো তৈরি হয়।
  • CustomScrollView এবং Slivers: একটি কাস্টম স্ক্রলিং UI তৈরি করতে এবং বিভিন্ন ধরণের Widget (যেমন SliverAppBar, SliverList, SliverGrid) একত্রে ব্যবহৃত হয়।

Sliver Widgets এর উদাহরণ:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Advanced Sliver Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: SliverScreen(),
    );
  }
}

class SliverScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        slivers: [
          SliverAppBar(
            expandedHeight: 200,
            pinned: true,
            flexibleSpace: FlexibleSpaceBar(
              title: Text('SliverAppBar'),
              background: Image.network(
                'https://via.placeholder.com/400',
                fit: BoxFit.cover,
              ),
            ),
          ),
          SliverList(
            delegate: SliverChildBuilderDelegate(
              (context, index) => ListTile(
                title: Text('Item $index'),
              ),
              childCount: 20,
            ),
          ),
        ],
      ),
    );
  }
}

উদাহরণের ব্যাখ্যা:

  1. SliverAppBar:
    • এটি একটি স্ক্রোলেবল AppBar তৈরি করে যা স্ক্রল করার সময় ছোট হয়ে যায় এবং একটি ব্যাকগ্রাউন্ড ইমেজ প্রদর্শন করে।
  2. SliverList:
    • এটি ডাইনামিকভাবে একটি লিস্ট তৈরি করে, যা স্ক্রোলিংয়ের সাথে তাল মিলিয়ে অ্যাপের UI কে ইন্টারেক্টিভ করে তোলে।

Complex UI এবং Advanced Widgets এর সুবিধা:

ইন্টারেক্টিভ এবং রেসপন্সিভ ডিজাইন:

  • Advanced Widgets এবং Complex UI ব্যবহার করে রেসপন্সিভ এবং ইন্টারেক্টিভ ডিজাইন তৈরি করা যায়, যা ব্যবহারকারীর অভিজ্ঞতা উন্নত করে।

স্ক্রলিং এবং লিস্ট পরিচালনা:

  • ListView.builder, GridView, এবং Sliver Widgets ব্যবহার করে স্ক্রলিং এবং লিস্ট ম্যানেজমেন্ট সহজে করা যায়।

কাস্টমাইজেশন এবং স্টাইলিং:

  • Custom Widgets এর মাধ্যমে আপনি UI উপাদানগুলিকে প্রয়োজনমত স্টাইল এবং কাস্টমাইজ করতে পারেন, যা আপনার অ্যাপকে আলাদা করে তোলে।

সংক্ষেপে:

  • Complex UI তৈরি করতে হলে UI কে ছোট ছোট অংশে ভাগ করে প্রতিটি অংশের জন্য পৃথক Widget তৈরি করুন।
  • Advanced Widgets এবং Custom Widgets ব্যবহার করে UI ডিজাইনকে মডুলার এবং পুনঃব্যবহারযোগ্য করুন।
  • Flutter এর প্রি-বিল্ট Advanced Widgets, যেমন Sliver Widgets, ListView.builder, এবং GridView ব্যবহার করে Complex UI তৈরি করুন।

Flutter এ এই পদ্ধতিগুলো ব্যবহার করে আপনি আকর্ষণীয়, রেসপন্সিভ এবং ইন্টারেক্টিভ Complex UI এবং Advanced Widgets তৈরি করতে সক্ষম হবেন।

Content added By
Promotion
NEW SATT AI এখন আপনাকে সাহায্য করতে পারে।

Are you sure to start over?

Loading...